MyBatis(十一)扩展:自定义类型处理器 您所在的位置:网站首页 mybatis typehandler接口 MyBatis(十一)扩展:自定义类型处理器

MyBatis(十一)扩展:自定义类型处理器

2023-08-17 04:16| 来源: 网络整理| 查看: 265

一、TypeHandler

  TypeHandler 在MyBatis中进行数据库类型和JavaBean类型的映射。

  TypeHandler 接口:

 

     该接口中声明了四个抽象方法,说明如下:

//将parameter对象转换为字符串存入到 ps 对象的i位置 public abstract void setNonNullParameter(PreparedStatement ps, int i, T parameter, JdbcType jdbcType) throws SQLException; //从结果集中获取数据库对应查询结果 //将字符串还原为原始的T类型对象 public abstract T getNullableResult(ResultSet rs, String columnName) throws SQLException; public abstract T getNullableResult(ResultSet rs, int columnIndex) throws SQLException; public abstract T getNullableResult(CallableStatement cs, int columnIndex) throws SQLException;

  

  BaseHandler 类:

 

     BaseTypeHandler 抽象类实现了上面的四个抽象方法,做了简单的包装,然后又留出四个抽象方法。

 

  TypeHandle 的子类:

    

 

  所有的类型处理器都直接或间接继承了 TypeHandler类。

 

二、MyBatis 处理枚举类型

  如果我们在 Employee 中又新增一个枚举类型的属性来表示员工的状态,那么在 MyBatis 里面会如何保存的呢?

  员工状态枚举类 EmpStatus:

public enum EmpStatus { LOGIN(100, "用户登录"), LOGOUT(200, "用户退出"), REMOVE(300, "用户不存在"); private Integer code; private String msg; private EmpStatus(Integer code, String msg) { this.code = code; this.msg = msg; } public Integer getCode() { return code; } public void setCode(Integer code) { this.code = code; } public String getMsg() { return msg; } public void setMsg(String msg) { this.msg = msg; } //根据状态码返回枚举对象 public static EmpStatus getEmpStatusByCode(Integer code) { switch (code) { case 100: return LOGIN; case 200: return LOGOUT; case 300: return REMOVE; default: return LOGOUT; } } }

 

  Employee 类:

public class Employee { private Integer id; private String lastName; private String gender; private String email; private EmpStatus empStatus = EmpStatus.LOGOUT; }

 

  接口中添加方法:

public Long addEmp(Employee employee);

 

  SQL映射文件配置:

insert into tbl_employee(`last_name`, `email`, `gender`, `empStatus`) values(#{lastName}, #{email}, #{gender}, #{empStatus})

 

  测试:

   @Test public void testEnum() throws IOException { //1、获取 sqlSessionFactory SqlSessionFactory sqlSessionFactory = getsqlSessionFactory(); //2、获取 sqlSession 实例,获取批量执行器 SqlSession sqlSession = sqlSessionFactory.openSession(); try { //3、获取接口的实现类对象 EmployeeMapper employeeMapper = sqlSession.getMapper(EmployeeMapper.class); Employee emp = new Employee(null, "test_enum", "1", "[email protected]", EmpStatus.LOGIN); employeeMapper.addEmp(emp); sqlSession.commit(); } finally { sqlSession.close(); } }

 

  运行结果:

 

   可以看到默认情况下MyBatis处理枚举类型使用的是 EnumTypeHandler。

 

   如果要使用 EnumOrdinalTypeHandler 类型呢?

 

 

   可以看到如果配置的 EnumOridnalTypeHandler 类型处理器,保存的就会是枚举的索引值?

  如何配置呢?

  在 MyBatis 的核心配置文件中配置如下内容:

 

  测试效果:

 

 

   这是在数据库保存的就是枚举的索引值了。

  小结:

  默认myBatis在处理枚举的时候保存的是枚举的名字:EnumTypeHandler。

  改变使用:EnumOrdinalTypeHandler,在核心配置文件中进行设置

  

 

三、自定义 TypeHandler 处理枚举

  如果我们想要自己自定义保存的数据呢?

  我们可以通过自定义TypeHandler的形式来在设置参数或者取出结果集的时候自定义参数封装策略。

  步骤:

  (1)实现TypeHandler接口或者继承BaseTypeHandler;

  (2)使用@MappedTypes定义处理的java类型,使用@MappedJdbcTypes定义jdbcType类型;

  (3)在自定义结果集标签或者参数处理的时候声明使用自定义TypeHandler进行处理或者在全局配置TypeHandler要处理的javaType

  自定义枚举类型的 TypeHandler:

/** * * 1、实现 TypeHandler 接口或者继承 BaseTypeHandler */ public class MyEnumEmpStatusTypeHandler implements TypeHandler { /** * 定义当前数据如何保存到数据库中 * @param ps * @param i * @param parameter * @param jdbcType * @throws SQLException */ @Override public void setParameter(PreparedStatement ps, int i, EmpStatus parameter, JdbcType jdbcType) throws SQLException { System.out.println("要保存的状态码:" + parameter.getCode()); ps.setString(i, parameter.getCode().toString()); } @Override public EmpStatus getResult(ResultSet rs, String columnName) throws SQLException { int code = rs.getInt(columnName); //需要根据从数据库中拿到的枚举状态码返回一个枚举对象 EmpStatus empStatus = EmpStatus.getEmpStatusByCode(code); return empStatus; } @Override public EmpStatus getResult(ResultSet rs, int columnIndex) throws SQLException { int code = rs.getInt(columnIndex); EmpStatus empStatus = EmpStatus.getEmpStatusByCode(code); return empStatus; } @Override public EmpStatus getResult(CallableStatement cs, int columnIndex) throws SQLException { int code = cs.getInt(columnIndex); EmpStatus empStatus = EmpStatus.getEmpStatusByCode(code); return empStatus; } }

 

 

  在 MyBatis 的核心配置文件中进行配置:

 

  其他方式:

  保存的时候给字段执行处理器:

insert into tbl_employee(`last_name`, `email`, `gender`, `empStatus`) values(#{lastName}, #{email}, #{gender}, #{empStatus, typeHandler="全类名"})

 

  在查询的时候通过自定义 resultMap 来给字段指定处理器:

select id, last_name lastName, email, gender, empStatus from tbl_employee where id = #{id}

 

 

  测试插入与查询:

@Test public void testEnum() throws IOException { //1、获取 sqlSessionFactory SqlSessionFactory sqlSessionFactory = getsqlSessionFactory(); //2、获取 sqlSession 实例,获取批量执行器 SqlSession sqlSession = sqlSessionFactory.openSession(); try { //3、获取接口的实现类对象 EmployeeMapper employeeMapper = sqlSession.getMapper(EmployeeMapper.class); //Employee emp = new Employee(null, "test_enum", "1", "[email protected]", EmpStatus.LOGIN); //employeeMapper.addEmp(emp); sqlSession.commit(); Employee empById = employeeMapper.getEmpById(13); System.out.println("empById = " + empById); System.out.println("员工状态:" + empById.getEmpStatus()); } finally { sqlSession.close(); } }

 

  运行结果:

 

 

   可以看到数据库保存的是我们自定义的值。

 

   控制台打印的也是根据 code 获取的枚举类型。

 



【本文地址】

公司简介

联系我们

今日新闻

    推荐新闻

    专题文章
      CopyRight 2018-2019 实验室设备网 版权所有